"""
Copyright (C) 2017 Open Source Robotics Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from geometry.point import Point
from geometry.line_segment import LineSegment


class BoundingBox(object):

    def __init__(self, origin, corner):
        self.origin = origin
        self.corner = corner
        self._normalize()

    @classmethod
    def from_boxes(cls, box_list):
        if not box_list:
            raise ValueError("box_list can't be empty")
        whole_merge = box_list[0]
        for i in range(1, len(box_list)):
            whole_merge = whole_merge.merge(box_list[i])
        return whole_merge

    def __hash__(self):
        return hash(hash(origin), hash(corner))

    def __eq__(self, other):
        return self.origin == other.origin and self.corner == other.corner

    def includes_point(self, point):
        return (self.origin <= point) and (point <= self.corner)

    def merge(self, other):
        merge_origin = self.origin.min(other.origin)
        merge_corner = self.corner.max(other.corner)
        return BoundingBox(merge_origin, merge_corner)

    def translate(self, point):
        new_origin = self.origin + point
        new_corner = self.corner + point
        return BoundingBox(new_origin, new_corner)

    def width(self):
        return self.corner.x - self.origin.x

    def height(self):
        return self.corner.y - self.origin.y

    def top_left(self):
        return Point(self.corner.x, self.origin.y)

    def top_right(self):
        return self.corner.clone()

    def bottom_left(self):
        return self.origin.clone()

    def bottom_right(self):
        return Point(self.origin.x, self.corner.y)

    def perimeter(self):
        return [
            LineSegment(self.top_left(), self.top_right()),
            LineSegment(self.top_right(), self.bottom_right()),
            LineSegment(self.bottom_right(), self.bottom_left()),
            LineSegment(self.bottom_left(), self.top_left())
        ]

    def _normalize(self):
        new_origin = self.origin.min(self.corner)
        new_corner = self.origin.max(self.corner)
        self.origin = new_origin
        self.corner = new_corner
